<template>
	<div :class="inputClass" v-clickoutside="handleClickOutside" @click="handleFocusEvent">
		<template v-for="(num, idx) in 4">
			<span class="dot" v-if="idx !== 0">.</span>
			<input ref="ipInputs" v-bind="inputConfig" v-model="ipAddress[idx]" @input="handleInputEvent(idx)" @keyup="handleKeyupEvent($event, idx)" />
		</template>
		<i v-if="!!this.clearable" :class="closeIconClass" @click.stop="handleClearData()"></i>
		<input class="el-input__inner placeholder" v-if="isInputFocus" :placeholder="placeholder" readonly />
	</div>
</template>

<script>
import emitter from 'element-ui/src/mixins/emitter';
import Clickoutside from 'element-ui/src/utils/clickoutside';
export default {
	name: 'swIpInput',
	mixins: [emitter],
	inject: { elForm: { default: () => null } },
	props: {
		value: { type: String, default: '' },
		disabled: { type: Boolean, default: false },
		clearable: { type: Boolean, default: false },
		placeholder: { type: String, default: '请输入IP地址' }
	},
	data() {
		return {
			ipString: this.value,
			ipAddress: [],
			isFocus: false
		};
	},
	directives: { Clickoutside },
	computed: {
		isDisabled() {
			return !this.disabled && !this.elForm.disabled;
		},
		isInputFocus() {
			return !this.isFocus && this.ipAddress.length === 0;
		},
		inputClass() {
			let inputClass = 'el-input sw_ip_input';
			if (!!this.elForm.size) {
				inputClass = `${inputClass} el-input--${this.elForm.size}`;
			}
			if (!this.isDisabled) {
				inputClass = `${inputClass} is-disabled`;
			}
			if (!this.isInputFocus) {
				inputClass = `${inputClass} is-focus`;
			}
			return `${inputClass}`;
		},
		closeIconClass() {
			return `el-icon-circle-close ${this.isFocus && this.ipString ? 'show' : ''}`;
		},
		inputConfig() {
			return {
				type: 'text',
				maxlength: 3,
				class: 'el-input__inner',
				disabled: !this.isDisabled
			};
		}
	},
	watch: {
		value(val) {
			this.ipString = val;
		},
		ipString(val) {
			this.$emit('input', val);
			this.ipAddress = !val ? [] : val.split('.');
			this.dispatch('ElFormItem', 'el.form.change', [val]);
		},
		ipAddress: {
			handler(arr) {
				let ipArrs = arr.filter((n) => !!n);
				this.ipString = ipArrs.join('.');
			},
			deep: true
		}
	},
	mounted() {
		this.$el.addEventListener('paste', (e) => {
			e.preventDefault();
			this.clipboardTextData(e);
		});
	},
	methods: {
		//粘贴文本内容
		clipboardTextData(e) {
			let clipboardData = e.clipboardData || window.clipboardData;
			this.ipString = clipboardData.getData('text');
		},

		//获取焦点时定位空白文本框
		positionEmptyInput(len) {
			if (len === 0) {
				this.$refs['ipInputs'][0].focus();
			} else if (len < 4) {
				this.$refs['ipInputs'][len].focus();
			} else {
				this.$refs['ipInputs'][3].focus();
			}
		},

		handleFocusEvent(e) {
			let len = this.ipAddress.length;
			if (e.target.nodeName === 'INPUT') {
				let value = e.target.value;
				if (!!value) return false;
				this.positionEmptyInput(len);
			} else {
				this.positionEmptyInput(len);
			}
			this.isFocus = true;
		},

		handleClickOutside() {
			this.isFocus = false;
		},

		handleInputEvent(index) {
			let value = this.ipAddress[index];
			value = value.replace(/[^0-9]/g, '');
			if (value.length > 1 && value[0] === '0') {
				value = value.replace(/^0+/, '');
			} else if (value.length === 3) {
				value = Number(value) > 255 ? '255' : value;
				if (index === 3) return false;
				this.$refs['ipInputs'][index].blur();
				this.$refs['ipInputs'][index + 1].focus();
			}
			this.ipAddress[index] = value;
		},

		handleKeyupEvent(event, index) {
			let value = this.ipAddress[index];
			if (event.keyCode === 110 && !!value && index < 3) {
				this.$refs['ipInputs'][index].blur();
				this.$refs['ipInputs'][index + 1].focus();
			}
			if (event.keyCode === 8 && !value && index > 0) {
				this.$refs['ipInputs'][index].blur();
				this.$refs['ipInputs'][index - 1].focus();
			}
		},

		handleClearData() {
			this.ipString = '';
			this.isFocus = false;
		}
	}
};
</script>

<style lang="scss" scoped>
:deep(.sw_ip_input) {
	display: inline-flex;
	align-items: center;
	border-radius: 4px;
	border: solid 1px #dcdfe6;
	box-sizing: border-box;
	overflow: hidden;
	min-width: 182px;
	padding: 0 10px;
	cursor: text;
	width: 100%;
	transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
	&:has(.el-input__inner:focus) {
		border-color: var(--primary);
	}
	&:hover {
		border-color: #c0c4cc;
		i.el-icon-circle-close {
			display: block;
		}
	}
	&.is-disabled {
		cursor: not-allowed;
		background-color: #f5f7fa;
	}
	.el-input__inner {
		padding: 0;
		margin: -1px 0;
		min-width: 32px;
		text-align: center;
		border-color: transparent;
		pointer-events: none;
	}
	.placeholder {
		position: absolute;
		top: 0;
		left: 0;
		margin: 0;
		width: 100%;
		height: 100%;
		padding: 0 15px;
		text-align: left;
		z-index: 1;
	}
	&.is-focus .el-input__inner {
		pointer-events: auto;
	}
	span.dot {
		font-size: 16px;
		line-height: 20px;
	}
	&:has(.el-icon-circle-close) {
		padding-right: 30px;
	}
	i.el-icon-circle-close {
		position: absolute;
		top: 50%;
		padding: 0;
		z-index: 2;
		right: 10px;
		color: #c0c4cc;
		cursor: pointer;
		transform: translateY(-50%);
		display: none;
		&.show {
			display: block;
		}
	}
}
</style>
